package code;


import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.security.InvalidKeyException;
import java.util.ArrayList;
import java.util.ListIterator;
import java.util.Scanner;
import java.util.StringTokenizer;

import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec;


public class SymmetricEncDec {
	//picture encryption icin fileinputstream calismio
	static byte[]          ivBytesDES = new byte[] {
		0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00 };
	static byte[]          ivBytesAES = new byte[] {
		0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00 };


	public void encrypt(SecretKey key, String padding, String file){
		try {
			System.out.println("encrypt");
			System.out.println("\n\n\n\n\n padding: "+padding+" file: "+file);
			Cipher cipher = Cipher.getInstance(padding, "BC");

			if(parseMode(padding).equals("CBC")||parseMode(padding).equals("OFB")||parseMode(padding).equals("CFB")){
				IvParameterSpec ivSpec;
				if(parseType(padding).equals("DES")||parseType(padding).equals("DESede")){
					ivSpec = new IvParameterSpec(ivBytesDES);
				}else{
					ivSpec = new IvParameterSpec(ivBytesAES);
				}

				cipher.init(Cipher.ENCRYPT_MODE, key, ivSpec);

			}
			else{
				cipher.init(Cipher.ENCRYPT_MODE, key);
			}
			FileInputStream inFile = new FileInputStream(file);

			byte[] input = new byte[64];
			int bytesRead;
			ArrayList<byte[]> out = new ArrayList<byte[]>();
			while ((bytesRead = inFile.read(input)) != -1)
			{		
				byte[] output = cipher.update(input, 0, bytesRead);
				if (output != null) out.add(output);
			}

			byte[] output = cipher.doFinal();
			if (output != null)  out.add(output);

			inFile.close();
			FileOutputStream outFile = new FileOutputStream(file);
			ListIterator iterator= out.listIterator();
			while(iterator.hasNext()){
				output =(byte [])iterator.next();
				outFile.write(output);
			}

			outFile.close();
			System.out.println("encrypted");

		} catch (Exception e) {
			e.printStackTrace();
		}

	}
	public void decrypt(SecretKey key, String padding, String file){
		try {
			System.out.println("decrypt");
			Cipher cipher = Cipher.getInstance(padding , "BC");


			if(parseMode(padding).equals("CBC")||parseMode(padding).equals("OFB")||parseMode(padding).equals("CFB")){
				IvParameterSpec ivSpec;
				if(parseType(padding).equals("DES")||parseType(padding).equals("DESede")){
					ivSpec = new IvParameterSpec(ivBytesDES);
				}else{
					ivSpec = new IvParameterSpec(ivBytesAES);
				}

				cipher.init(Cipher.DECRYPT_MODE, key, ivSpec);

			}
			else{
				cipher.init(Cipher.DECRYPT_MODE, key);
			}
			FileInputStream inFile = new FileInputStream(file);


			byte[] input = new byte[64];
			int bytesRead;
			ArrayList<byte[]> out = new ArrayList<byte[]>();
			while ((bytesRead = inFile.read(input)) != -1)
			{		
				byte[] output = cipher.update(input, 0, bytesRead);
				if (output != null) out.add(output);
			}

			byte[] output = cipher.doFinal();
			if (output != null)  out.add(output);

			inFile.close();
			FileOutputStream outFile = new FileOutputStream(file);
			ListIterator iterator= out.listIterator();
			while(iterator.hasNext()){
				output =(byte [])iterator.next();
				outFile.write(output);
			}

			outFile.close();
			System.out.println("decrypted");


		} catch (Exception e) {
			e.printStackTrace();
		}


	}
	public String parseMode(String padding){
		String mode=padding;
		if(padding.contains("/")){
			StringTokenizer st = new StringTokenizer(padding, "/");
			st.nextToken();
			mode=st.nextToken();
		}


		return mode;

	}
	public String parseType(String padding){
		String type=padding;

		if(padding.contains("/")){
			StringTokenizer st = new StringTokenizer(padding, "/");
			type=st.nextToken();
		}
		return type;

	}

}


